package com.cool.shark.service.Impl;

import com.cool.shark.ex.ServiceException;
import com.cool.shark.mapper.GoodsMapper;
import com.cool.shark.mapper.OrderMapper;
import com.cool.shark.pojo.dto.OrderInserDto;
import com.cool.shark.pojo.entity.Goods;
import com.cool.shark.pojo.entity.Order;
import com.cool.shark.pojo.vo.GoodsStandardVo;
import com.cool.shark.pojo.vo.OrderStandardVo;
import com.cool.shark.pojo.vo.orderNumVo;
import com.cool.shark.service.OrderService;
import com.cool.shark.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
 * @Name: OrderServiceImpl
 * @Author: 西风残叶
 * @Date: 2024/4/29 23:08
 * @Version: 1.0
 * @TODO: TODO
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper mapper;
    @Autowired
    private GoodsMapper goodsMapper;
    /**
     * 将一个订单插入到数据库中。
     *
     * @param orderInsertDto 需要插入的订单对象，包含订单的所有相关信息。
     *              该对象不应为空，否则会导致插入失败。
     * @return 该方法没有返回值，订单插入操作的结果通常通过异常处理或日志记录来反馈。
     * 如果插入成功，通常会记录一条成功信息；如果插入失败，会抛出相应的异常。
     */
    @Override
    public void insert(OrderInserDto orderInsertDto) {
        log.info("开始处理已插入订单业务,参数:{}", orderInsertDto);
        if (orderInsertDto.getRecipients()==null|| orderInsertDto.getRecipients().isEmpty()){
            String message = "收件人不能为空";
            throw new ServiceException(ServiceCode.ERR_BAD_REQUEST, message);
        }
        if (orderInsertDto.getPhone()==null){
            String message = "手机号不能为空";
            throw new ServiceException(ServiceCode.ERR_BAD_REQUEST, message);
        }
        if (orderInsertDto.getPhone().
                matches("^(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$,")||
        orderInsertDto.getPhone().isEmpty()){
            String message = "手机号格式错误";
            throw new ServiceException(ServiceCode.ERR_BAD_REQUEST, message);
        }
        if (orderInsertDto.getAddress()==null|| orderInsertDto.getAddress().isEmpty()){
            String message = "收货地址不能为空";
            throw new ServiceException(ServiceCode.ERR_BAD_REQUEST, message);
        }
        Order order = new Order();
        BeanUtils.copyProperties(orderInsertDto,order);
        log.info("订单信息:{}",order);
        order.setOrderId("CS"+System.currentTimeMillis());
        order.setPrice(orderInsertDto.getPrice().multiply(BigDecimal.valueOf(orderInsertDto.getNum())));
        log.info("订单信息:{}",order);
        int insert = mapper.insert(order);
        if (insert!=1){
            String message = "下单失败,服务器忙!";
            throw new ServiceException(ServiceCode.ERR_INSERT_FAILED, message);
        }
        GoodsStandardVo goodsStandard = goodsMapper.getGoodsStandard(orderInsertDto.getSpuId());
        Goods goods = new Goods();
        goods.setSpuId(orderInsertDto.getSpuId());
        goods.setSaleCount(orderInsertDto.getNum());
        goods.setStock(goodsStandard.getStock()-orderInsertDto.getNum());
        int update = goodsMapper.update(goods);
        if (update!=1){
            String message = "下单失败,服务器忙!";
            throw new ServiceException(ServiceCode.ERR_UPDATE_FAILED, message);
        }
        log.info("订单插入成功");
    }

    /**
     * 获取订单标准视图列表。
     *
     * <p>该方法不接受任何参数，返回一个订单标准视图的列表。订单标准视图包含订单的基本信息，用于前端展示或进一步处理。
     *
     * @return 返回一个包含订单标准视图的列表。列表中的每个元素都代表一个订单的标准视图。
     */
    @Override
    public List<OrderStandardVo> list(Long userId) {
        log.info("开始处理根据用户id查询订单业务,参数:{}", userId);
        List<OrderStandardVo> list = mapper.list(userId);
        log.info("订单列表:{}",list);
        return list;
    }

    /**
     * 根据用户ID查询订单数量
     *
     * @param userId 用户的唯一标识符
     * @return 返回一个包含订单统计信息的列表，每个订单统计信息包含订单的各种标准字段
     */
    @Override
    public List<orderNumVo> orderNum(Long userId) {
        log.info("开始处理根据用户id查询订单数量业务,参数:{}", userId);
        List<orderNumVo> orderNumVos = mapper.orderNum(userId);
        return orderNumVos;
    }
}
